/*
dictionary.h
(c) 2010 Yury Hamenkov
This file is part of qWordCards.

qWordCards is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

qWordCards is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with qWordCards. If not, see <http://www.gnu.org/licenses/>.
*/

/* This class provides to read and decompress data from stardict dictionary with pseudo-random access
*/

#ifndef DICTZIPLOADER_H
#define DICTZIPLOADER_H

#include <zlib.h>		// for deflate decompression
#include <fstream>
#include "wordindex.h"
#include <QString>

#define OUT_BUFFER_SIZE 0xffffL // 65 535
#define IN_BUFFER_SIZE ((unsigned long)((double)(OUT_BUFFER_SIZE - 12) * 0.89))

namespace qWordCards {
	class DICTZIPLoader
	{
	public:
		enum GZIP_TYPE {
			UNKNOWN = 0,
			TEXT = 1,
			GZIP = 2,
			DZIP = 3
		};
		
	private:
		// GZIP header data (see RFC 1952):
		unsigned char		ID1;
		unsigned char		ID2;
		char				CM;
		char				FLG;
		long int			MTIME;
		char				XFL;
		char				OS;
		
		// zlib stream
		z_stream			zStream;
		
		// File metadata
		GZIP_TYPE			type; 						// GZIP file type
		QString				fileName; 					// file name
		bool				loaded; 					// is file loaded
		bool				initialized; 				// is zstream initialized
		unsigned long int	headerLength; 				// length of the file header area
		
		// Additional header data:
		char* 				FLG_FNAME;					// FLG_FNAME chunk
		char* 				FLG_FCOMMENT;				// FLG_COMMENT chunk
		unsigned short int 	FLG_FHCRC;					// FLG_FHCRC chunk
		
		// FLG_FEXTRA structure
		unsigned short int 	FLG_FEXTRA_XLEN;
		char 				FLG_FEXTRA_SI1;
		char 				FLG_FEXTRA_SI2;
		unsigned short int 	FLG_FEXTRA_LEN;
		
		// dictzip extra chunk data:
		unsigned short int 	FLG_FEXTRA_DZIP_VER;
		unsigned short int 	FLG_FEXTRA_DZIP_CHLEN; 		// the length of a "chunk" of data
		unsigned short int 	FLG_FEXTRA_DZIP_CHCNT; 		// how many chunks are preset
		short int* 			FLG_FEXTRA_DZIP_CHUNKS;		// хранит длины чанков данных
		unsigned long int* 	FLG_FEXTRA_DZIP_OFFSETS;	// Calculated data chunk offsets
		
	public:
		
		DICTZIPLoader(QString _fileName);
		
		~DICTZIPLoader();
		
		bool Load();
		void PrintDetailData();
		QString ReadData (unsigned long int start, unsigned long int size);
	};
}
#endif // DICTZIPLOADER_H
